using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using AutoMapper;
using Common.Enumerations;
using Common.Views;
using Sanelib.Core;
using WebApp.Extensions;
using WebApp.Services;

namespace WebApp.Controllers
{
    public class SmartController : Controller
    {
        protected IUserSession UserSession { get; private set; }
        protected IMappingEngine MappingEngine { get; private set; }

        public SmartController(IUserSession userSession, IMappingEngine mappingEngine)
        {
            UserSession = userSession;
            MappingEngine = mappingEngine;
        }

        public void EnsureCurrentUserHas(Permission permission)
        {
            var currentUser = GetCurrentUser();
            if (!currentUser.HasPermission(permission))
                throw new HttpException(401, "You are not authorized to view this resource.");
        }
        public bool CurrentUserHas(Permission permission)
        {
            var currentUser = GetCurrentUser();
            return currentUser.HasPermission(permission);
        }

        protected MemberView GetCurrentUser()
        {
            return UserSession.GetCurrentUser();
        }

        protected override void OnException(ExceptionContext filterContext)
        {
            base.OnException(filterContext);

            var rawUrl = System.Web.HttpContext.Current.Request.RawUrl;
            var baseException = filterContext.Exception;

            Logger.Log(LogType.Error, this, string.Format("--------------------------------------------------------------------------"));
            Logger.Log(LogType.Error, this, string.Format("{0}. RawUrl={1}", baseException.Message, rawUrl), baseException);
            Logger.Log(LogType.Error, this, string.Format("--------------------------------------------------------------------------"));
        }

        protected ActionResult ReportResult(string reportTitle, DataTable dataTable, bool skipSuffix = false)
        {
            ViewBag.Title = skipSuffix ? reportTitle : string.Format("{0} Report", reportTitle);

            var excelFilename = reportTitle + ".xlsx";

            var result = new ExcelFileResult(reportTitle, dataTable, excelFilename);
            return result;
        }

        protected RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression)
        {
            return RedirectToActionCore(actionExpression, null);
        }

        protected RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression, IDictionary<string, object> dictionary)
        {
            return RedirectToActionCore(actionExpression, dictionary);
        }

        protected RedirectToRouteResult RedirectToAction<TController>(Expression<Func<TController, object>> actionExpression, object values)
        {
            return RedirectToActionCore(actionExpression, new RouteValueDictionary(values));
        }

        private RedirectToRouteResult RedirectToActionCore<TController>(Expression<Func<TController, object>> actionExpression, IDictionary<string, object> dictionary)
        {
            var controllerName = typeof(TController).GetControllerName();
            var actionName = actionExpression.GetActionName();

            var routeDictionary = dictionary == null ? new RouteValueDictionary() : new RouteValueDictionary(dictionary);

            routeDictionary.ProcessArea(typeof(TController));

            return RedirectToAction(actionName, controllerName, routeDictionary);
        }
    }
}